﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WordNet.Core.Util;

namespace WordNet.Core.Graph
{
    public class ASPath:IASPath
    {
        private IDigraph _graph;

        public ASPath(IDigraph g)
        {
            if (g == null)
                throw new ArgumentNullException(Message.NullException);
            _graph = g; 
        }
        
        public int Length(int vertexOne, int vertexTwo)
        {
            if (NotInRange(vertexOne, vertexTwo))
                throw new ArgumentOutOfRangeException(Message.OutOfRange);
            
            return Search(vertexOne, vertexTwo).PathLength;
        }

        // length of shortest ancestral path between any vertex in v 
        //and any vertex in w; -1 if no such path
        public int Length(IEnumerable<int> v, IEnumerable<int> w)
        {
            if (v == null || w == null)
                throw new ArgumentNullException(Message.NullException);
            return Search(v, w).PathLength;
        }

        public int Ancestor(int vertexOne, int vertexTwo)
        {
            if (NotInRange(vertexOne, vertexTwo))
                throw new ArgumentOutOfRangeException(Message.OutOfRange);
            return Search(vertexOne, vertexTwo).Ancestor; 
        }

        // a common ancestor that participates in shortest ancestral 
        // path; -1 if no such path
        public int Ancestor(IEnumerable<int> v, IEnumerable<int> w)
        {
            if (v == null || w == null)
                throw new ArgumentNullException(Message.NullException);
            return Search(v, w).Ancestor; 
        }

        private IFindAncestor Search(int v, int w)
        {
            IShortestPath v_path = new DirectedShortestPath(_graph, v);
            IFindAncestor findAncestor = new FindAncestor(_graph, w, v_path);
            return findAncestor;
        }

        private IFindAncestor Search(IEnumerable<int> v, IEnumerable<int> w)
        {
            IShortestPath v_path = new DirectedShortestPath(_graph, v);
            IFindAncestor findAncestor = new FindAncestor(_graph, w, v_path);
            return findAncestor;
        }

        private bool NotInRange(int v, int w)
        {
            return (v < 0 || w < 0 );
        }
    }
}
